//
//  iChatStatz.m
//  Statz
//
//  Created by dmaclach on 6/17/07.
//
// Copyright 2007 Google Inc.
// 
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License.  You may obtain a copy
// of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
// License for the specific language governing permissions and limitations under
// the License.
//

#import "iChatStatz.h"
#import "AEVTBuilder.h"
#import "StatusUpdate.h"

// Routines to handle adding and remove menu extras in HIServices (from ASM source)
int CoreMenuExtraGetMenuExtra(CFStringRef identifier, void *menuExtra);
int CoreMenuExtraAddMenuExtra(CFURLRef path, int position, int whoCares, int whoCares2, int whoCares3, int whoCares4);
int CoreMenuExtraRemoveMenuExtra(void *menuExtra, int whoCares);


@implementation iChatStatz
- (NSString*)appBundleID {
  return @"com.apple.iChat";
}

- (NSString*)uuid {
  return @"CD711531-2503-4B44-A450-16E387D65AA6";
}

- (StatzUpdateValue)updateStatz:(StatusUpdate*)sender {
  NSString *newValue = [sender status];
  OSType newState;
  switch ([sender state]) {
    case kStatzStateAway:
      newState = 'away';
      break;
      
    case kStatzStateInvisible:
      newState = 'invs';
      break;
      
    case kStatzStateOffline:
      newState = 'offl';
      break;
      
    default:
    case kStatzStateAvailable:
      newState = 'aval';
      break;
      
  }

  NSAppleEventDescriptor *descriptor = [AEVT class:kAECoreSuite 
                                                id:kAEGetData
                                    targetBundleID:[self appBundleID],
                                        [KEY : keyAEData], [STRING : newValue],
                                        [KEY : keyDirectObject],
                                        [RECORD : cObjectSpecifier,
                                         [KEY : keyAEKeyForm], [ENUM : formPropertyID],
                                         [KEY : keyAEDesiredClass], [TYPE : cProperty],
                                         [KEY : keyAEKeyData], [TYPE : 'smsg'],
                                         [KEY : keyAEContainer], [DESC null],
                                         ENDRECORD],
                                        ENDRECORD];
  require_ae_noerr(descriptor, cantUpdate);
  NSAppleEventDescriptor *reply = [descriptor sendWithImmediateReply];
  require_ae_noerr(reply, cantUpdate);
  NSAppleEventDescriptor *keyDirectDesc = [reply descriptorForKeyword:keyDirectObject];
  require_ae_noerr(keyDirectDesc, cantUpdate);
  NSString *oldStatus = [keyDirectDesc stringValue];
  
  descriptor = [AEVT class:kAECoreSuite 
                        id:kAEGetData
            targetBundleID:[self appBundleID],
                [KEY : keyDirectObject],
                [RECORD : cObjectSpecifier,
                 [KEY : keyAEKeyForm], [ENUM : formPropertyID],
                 [KEY : keyAEDesiredClass], [TYPE : cProperty],
                 [KEY : keyAEKeyData], [TYPE : 'stat'],
                 [KEY : keyAEContainer], [DESC null],
                 ENDRECORD],
                ENDRECORD];
  require_ae_noerr(descriptor, cantUpdate);
  reply = [descriptor sendWithImmediateReply];
  require_ae_noerr(reply, cantUpdate);
  keyDirectDesc = [reply descriptorForKeyword:keyDirectObject];
  require_ae_noerr(keyDirectDesc, cantUpdate);  
  OSType oldState = [keyDirectDesc enumCodeValue];
  if ([oldStatus isEqualTo:newValue] && oldState == newState) {
    return kStatzUpdateNotChanged;
  }
  descriptor = [AEVT class:kAECoreSuite 
                        id:kAESetData
            targetBundleID:[self appBundleID],
    [KEY : keyAEData], [STRING : newValue],
    [KEY : keyDirectObject],
      [RECORD : cObjectSpecifier,
        [KEY : keyAEKeyForm], [ENUM : formPropertyID],
        [KEY : keyAEDesiredClass], [TYPE : cProperty],
        [KEY : keyAEKeyData], [TYPE : 'smsg'],
        [KEY : keyAEContainer], [DESC null],
        ENDRECORD],
    ENDRECORD];
  require_ae_noerr(descriptor, cantUpdate);
  reply = [descriptor sendWithImmediateReply];
  require_ae_noerr(reply, cantUpdate);
 
  descriptor = [AEVT class:kAECoreSuite 
                       id:kAESetData
           targetBundleID:[self appBundleID],
   [KEY : keyAEData], [ENUM : newState],
   [KEY : keyDirectObject],
   [RECORD : cObjectSpecifier,
     [KEY : keyAEKeyForm], [ENUM : formPropertyID],
     [KEY : keyAEDesiredClass], [TYPE : cProperty],
     [KEY : keyAEKeyData], [TYPE : 'stat'],
     [KEY : keyAEContainer], [DESC null],
     ENDRECORD],
   ENDRECORD];
  require_ae_noerr(descriptor, cantUpdate);
  reply = [descriptor sendWithImmediateReply];
  require_ae_noerr(reply, cantUpdate);
  return kStatzUpdateSuccess;
cantUpdate:
  return kStatzUpdateError;
}

- (BOOL)appHasStatusMenuItem {
  char *menuItem = nil;
  CoreMenuExtraGetMenuExtra(CFSTR("com.apple.menuextra.iChat"), &menuItem);
  return menuItem != nil;
}

- (unsigned int)stateMenuMask { 
  return kStatzStateAvailable 
  | kStatzStateAway; 
  //| kStatzStateInvisible 
  //| kStatzStateOffline;
}

@end
